/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controllers;

import concursos.concurso.Sorteio;
import controllers.exceptions.NonexistentEntityException;
import controllers.exceptions.PreexistingEntityException;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import concursos.concurso.NormaComplementar;
import concursos.concurso.Ordem;
import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author lucena
 */
public class SorteioJpaController {

    public SorteioJpaController() {
        emf = Persistence.createEntityManagerFactory("concursosPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Sorteio sorteio) throws PreexistingEntityException, Exception {
        if (sorteio.getOrdem() == null) {
            sorteio.setOrdem(new HashSet<Ordem>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            NormaComplementar normaComplementar = sorteio.getNormaComplementar();
            if (normaComplementar != null) {
                normaComplementar = em.getReference(normaComplementar.getClass(), normaComplementar.getId());
                sorteio.setNormaComplementar(normaComplementar);
            }
            Set<Ordem> attachedOrdem = new HashSet<Ordem>();
            for (Ordem ordemOrdemToAttach : sorteio.getOrdem()) {
                ordemOrdemToAttach = em.getReference(ordemOrdemToAttach.getClass(), ordemOrdemToAttach.getId());
                attachedOrdem.add(ordemOrdemToAttach);
            }
            sorteio.setOrdem(attachedOrdem);
            em.persist(sorteio);
            if (normaComplementar != null) {
                normaComplementar.getSorteio().add(sorteio);
                normaComplementar = em.merge(normaComplementar);
            }
            for (Ordem ordemOrdem : sorteio.getOrdem()) {
                Sorteio oldSorteioOfOrdemOrdem = ordemOrdem.getSorteio();
                ordemOrdem.setSorteio(sorteio);
                ordemOrdem = em.merge(ordemOrdem);
                if (oldSorteioOfOrdemOrdem != null) {
                    oldSorteioOfOrdemOrdem.getOrdem().remove(ordemOrdem);
                    oldSorteioOfOrdemOrdem = em.merge(oldSorteioOfOrdemOrdem);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findSorteio(sorteio.getId()) != null) {
                throw new PreexistingEntityException("Sorteio " + sorteio + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Sorteio sorteio) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Sorteio persistentSorteio = em.find(Sorteio.class, sorteio.getId());
            NormaComplementar normaComplementarOld = persistentSorteio.getNormaComplementar();
            NormaComplementar normaComplementarNew = sorteio.getNormaComplementar();
            Set<Ordem> ordemOld = persistentSorteio.getOrdem();
            Set<Ordem> ordemNew = sorteio.getOrdem();
            if (normaComplementarNew != null) {
                normaComplementarNew = em.getReference(normaComplementarNew.getClass(), normaComplementarNew.getId());
                sorteio.setNormaComplementar(normaComplementarNew);
            }
            Set<Ordem> attachedOrdemNew = new HashSet<Ordem>();
            for (Ordem ordemNewOrdemToAttach : ordemNew) {
                ordemNewOrdemToAttach = em.getReference(ordemNewOrdemToAttach.getClass(), ordemNewOrdemToAttach.getId());
                attachedOrdemNew.add(ordemNewOrdemToAttach);
            }
            ordemNew = attachedOrdemNew;
            sorteio.setOrdem(ordemNew);
            sorteio = em.merge(sorteio);
            if (normaComplementarOld != null && !normaComplementarOld.equals(normaComplementarNew)) {
                normaComplementarOld.getSorteio().remove(sorteio);
                normaComplementarOld = em.merge(normaComplementarOld);
            }
            if (normaComplementarNew != null && !normaComplementarNew.equals(normaComplementarOld)) {
                normaComplementarNew.getSorteio().add(sorteio);
                normaComplementarNew = em.merge(normaComplementarNew);
            }
            for (Ordem ordemOldOrdem : ordemOld) {
                if (!ordemNew.contains(ordemOldOrdem)) {
                    ordemOldOrdem.setSorteio(null);
                    ordemOldOrdem = em.merge(ordemOldOrdem);
                }
            }
            for (Ordem ordemNewOrdem : ordemNew) {
                if (!ordemOld.contains(ordemNewOrdem)) {
                    Sorteio oldSorteioOfOrdemNewOrdem = ordemNewOrdem.getSorteio();
                    ordemNewOrdem.setSorteio(sorteio);
                    ordemNewOrdem = em.merge(ordemNewOrdem);
                    if (oldSorteioOfOrdemNewOrdem != null && !oldSorteioOfOrdemNewOrdem.equals(sorteio)) {
                        oldSorteioOfOrdemNewOrdem.getOrdem().remove(ordemNewOrdem);
                        oldSorteioOfOrdemNewOrdem = em.merge(oldSorteioOfOrdemNewOrdem);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                long id = sorteio.getId();
                if (findSorteio(id) == null) {
                    throw new NonexistentEntityException("The sorteio with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Sorteio sorteio;
            try {
                sorteio = em.getReference(Sorteio.class, id);
                sorteio.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The sorteio with id " + id + " no longer exists.", enfe);
            }
            NormaComplementar normaComplementar = sorteio.getNormaComplementar();
            if (normaComplementar != null) {
                normaComplementar.getSorteio().remove(sorteio);
                normaComplementar = em.merge(normaComplementar);
            }
            Set<Ordem> ordem = sorteio.getOrdem();
            for (Ordem ordemOrdem : ordem) {
                ordemOrdem.setSorteio(null);
                ordemOrdem = em.merge(ordemOrdem);
            }
            em.remove(sorteio);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Sorteio> findSorteioEntities() {
        return findSorteioEntities(true, -1, -1);
    }

    public List<Sorteio> findSorteioEntities(int maxResults, int firstResult) {
        return findSorteioEntities(false, maxResults, firstResult);
    }

    private List<Sorteio> findSorteioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Sorteio as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Sorteio findSorteio(long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Sorteio.class, id);
        } finally {
            em.close();
        }
    }

    public int getSorteioCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) em.createQuery("select count(o) from Sorteio as o").getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
